{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Load dependencies"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "%load_ext autoreload\n",
    "%autoreload 2\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2.0.0-alpha0\n",
      "GPU Available:  True\n"
     ]
    }
   ],
   "source": [
    "import os\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "from pathlib import Path\n",
    "import glob\n",
    "import pickle\n",
    "import json\n",
    "import matplotlib.pyplot as plt\n",
    "from lstm import LSTM_Simple\n",
    "from metrics import exact_match_metric, exact_match_metric_index\n",
    "from callbacks import NValidationSetsCallback, GradientLogger\n",
    "from tqdm import tqdm\n",
    "from evaluate_lstm import LSTM_Evaluator\n",
    "\n",
    "import sys\n",
    "sys.path.append('../../')\n",
    "from src.models.attention import LSTMWithAttention\n",
    "from src.models.generator import DataGenerator, DataGeneratorAttention\n",
    "\n",
    "from sklearn.model_selection import train_test_split\n",
    "import tensorflow as tf\n",
    "from tensorflow.keras.optimizers import Adam\n",
    "print(tf.__version__)\n",
    "print(\"GPU Available: \", tf.test.is_gpu_available())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Helper Function"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "def plot_two_results(result_1, result_2=None, experiments=['L&L'], title=''):\n",
    "    labels = []\n",
    "    array_1 = []\n",
    "    array_2 = []\n",
    "    \n",
    "    for module in result_1:\n",
    "        labels.append(module.split('__')[1])\n",
    "        array_1.append(result_1[module])\n",
    "\n",
    "    if result_2 is not None:\n",
    "        for module in result_1:\n",
    "            array_2.append(result_2[module])\n",
    "\n",
    "    x = np.arange(len(labels))  # the label locations\n",
    "    width = 0.35  # the width of the bars\n",
    "\n",
    "    fig, ax = plt.subplots()\n",
    "    if result_2 is not None:\n",
    "        rects1 = ax.bar(x - width/2, array_1, width, label=experiments[0])\n",
    "        rects2 = ax.bar(x + width/2, array_2, width, label=experiments[1])\n",
    "    else:\n",
    "        rects1 = ax.bar(x, array_1, width, label=experiments[0])\n",
    "\n",
    "\n",
    "    # Add some text for labels, title and custom x-axis tick labels, etc.\n",
    "    ax.set_ylabel('Scores')\n",
    "    ax.set_title('Evaluation scores: ' + title)\n",
    "    ax.set_xticks(x)\n",
    "    ax.set_xticklabels(labels, rotation=30, ha=\"right\")\n",
    "    ax.legend()\n",
    "\n",
    "\n",
    "    def autolabel(rects):\n",
    "        \"\"\"Attach a text label above each bar in *rects*, displaying its height.\"\"\"\n",
    "        for rect in rects:\n",
    "            height = rect.get_height()\n",
    "            ax.annotate('{0:.2f}'.format(height),\n",
    "                        xy=(rect.get_x() + rect.get_width() / 2, height),\n",
    "                        xytext=(0, 3),  # 3 points vertical offset\n",
    "                        textcoords=\"offset points\",\n",
    "                        ha='center', va='bottom')\n",
    "\n",
    "\n",
    "    if result_2 is not None:\n",
    "        autolabel(rects2)\n",
    "\n",
    "    autolabel(rects1)\n",
    "\n",
    "    fig.tight_layout()\n",
    "    plt.ylim([0, 1.1])\n",
    "    plt.legend(loc='lower right')\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "def concatenate_texts_individual(path, pattern):\n",
    "    file_paths = list(path.glob('{}*.txt'.format(pattern)))\n",
    "    \n",
    "    input_texts = {}\n",
    "    target_texts = {}\n",
    "\n",
    "    for file_path in file_paths:\n",
    "        if file_path.stem not in input_texts:\n",
    "            input_texts[file_path.stem] = []\n",
    "            target_texts[file_path.stem] = []\n",
    "        \n",
    "        with open(str(file_path), 'r', encoding='utf-8') as f:\n",
    "            lines = f.read().split('\\n')[:-1]\n",
    "\n",
    "        input_texts[file_path.stem].extend(lines[0::2])\n",
    "        target_texts[file_path.stem].extend(['\\t' + target_text + '\\n' for target_text in lines[1::2]])\n",
    "        \n",
    "    return input_texts, target_texts"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_data(settings_path):\n",
    "    with open(str(settings_path), 'r') as file:\n",
    "        settings_dict = json.load(file)\n",
    "\n",
    "    raw_path = Path(settings_dict['data_path'])/'raw/v1.0/'\n",
    "    interpolate_path = raw_path/'interpolate'\n",
    "    extrapolate_path = raw_path/'extrapolate'\n",
    "    train_easy_path = raw_path/'train-easy/'\n",
    "    \n",
    "    \n",
    "    math_module = settings_dict[\"math_module\"]\n",
    "    train_level = settings_dict[\"train_level\"]\n",
    "\n",
    "    datasets = {\n",
    "        'train':(raw_path, 'train-' + train_level + '/' + math_module),\n",
    "        'interpolate':(interpolate_path, math_module),\n",
    "        'extrapolate':(extrapolate_path, math_module)\n",
    "               }\n",
    "\n",
    "    input_texts = {}\n",
    "    target_texts = {}\n",
    "\n",
    "    for k, v in datasets.items():\n",
    "        input_texts[k], target_texts[k] = concatenate_texts_individual(v[0], v[1])\n",
    "    \n",
    "    return settings_dict, input_texts, target_texts"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "def evaluate_arithmetics_interpolate(lstm_eval, input_texts, target_texts, print_res=False):\n",
    "    test_set = 'interpolate'\n",
    "    results = {}\n",
    "\n",
    "    results_deepmind = {'arithmetic__add_or_sub': 0.875,\n",
    "                        'arithmetic__add_or_sub_in_base': 0.925,\n",
    "                        'arithmetic__add_sub_multiple': .89,\n",
    "                        'arithmetic__mul_div_multiple': .91,\n",
    "                        'arithmetic__nearest_integer_root': .9,\n",
    "                        'arithmetic__mul': 0.55,\n",
    "                        'arithmetic__div': 0.82,\n",
    "                        'arithmetic__simplify_surd':0.08,\n",
    "                        'arithmetic__mixed': 0.4}\n",
    "\n",
    "    for module in input_texts[test_set]:\n",
    "        metric = lstm_eval.evaluate_model(input_texts[test_set][module], target_texts[test_set][module])\n",
    "        if print_res:\n",
    "            print(test_set, module)\n",
    "            print('metric:', metric, '\\n')        \n",
    "        results[module] = metric\n",
    "\n",
    "    plot_two_results(results, results_deepmind, experiments=['L&L', 'DM'], title='interpolation')\n",
    "    \n",
    "    return results, results_deepmind"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "def evaluate_arithmetics_extrapolate(lstm_eval, input_texts, target_texts, print_res=False):\n",
    "    test_set = 'extrapolate'\n",
    "    results = {}\n",
    "\n",
    "    results_deepmind = {'arithmetic__add_or_sub_big': 0.82,\n",
    "                        'arithmetic__add_sub_multiple_longer': 0.22,\n",
    "                        'arithmetic__mul_big': .31,\n",
    "                        'arithmetic__mixed_longer': 0.02,\n",
    "                        'arithmetic__mul_div_multiple_longer': 0.34,\n",
    "                        'arithmetic__div_big':0.64}\n",
    "\n",
    "    for module in input_texts[test_set]:\n",
    "        \n",
    "        metric = lstm_eval.evaluate_model(input_texts[test_set][module], target_texts[test_set][module])\n",
    "        if print_res:\n",
    "            print(test_set, module)\n",
    "            print('metric:', metric, '\\n')\n",
    "        results[module] = metric\n",
    "\n",
    "    plot_two_results(results, results_deepmind, experiments=['L&L', 'DM'], title='extrapolation')\n",
    "    return results, results_deepmind"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "class LSTMWithAttentionEvaluator:\n",
    "    \n",
    "    def __init__(self, path):\n",
    "        \n",
    "        with open(str(path/'settings.json'), 'r') as file:\n",
    "            self.settings_dict = json.load(file)\n",
    "\n",
    "        with open(str(path/'arithmetic-*.pkl'), 'rb') as file:\n",
    "            self.sequence_data = pickle.load(file) \n",
    "            self.token_index = self.sequence_data['input_token_index']\n",
    "\n",
    "        self.num_tokens = len(self.token_index)\n",
    "        \n",
    "        adam = Adam(lr=6e-4, beta_1=0.9, beta_2=0.995, epsilon=1e-9, decay=0.0, amsgrad=False, clipnorm=0.1)\n",
    "        self.lstm = LSTMWithAttention(sequence_data['num_encoder_tokens'], \n",
    "                         sequence_data['num_decoder_tokens'], \n",
    "                         sequence_data['max_encoder_seq_length'],\n",
    "                        sequence_data['max_decoder_seq_length'],\n",
    "                        settings_dict['num_encoder_units'],\n",
    "                        settings_dict['num_decoder_units'],\n",
    "                        settings_dict['embedding_dim'])\n",
    "        self.model = self.lstm.get_model()\n",
    "        self.model.load_weights(str(path/'model.h5'))\n",
    "        self.model.compile(optimizer=adam, loss='categorical_crossentropy', metrics=[exact_match_metric])\n",
    "        \n",
    "    def evaluate_model(self, input_texts, output_texts, teacher_forcing=True, batch_size=128, n_samples=1000):\n",
    "        max_seq_length  = max([len(txt_in)+len(txt_out) for txt_in, txt_out in zip(input_texts,output_texts)])\n",
    "        \n",
    "        data_gen_pars = {\n",
    "            \"batch_size\": settings_dict['batch_size'],\n",
    "            \"max_encoder_seq_length\": sequence_data['max_encoder_seq_length'],\n",
    "            \"max_decoder_seq_length\": sequence_data['max_decoder_seq_length'],\n",
    "            \"num_encoder_tokens\": sequence_data['num_encoder_tokens'],\n",
    "            \"num_decoder_tokens\": sequence_data['num_decoder_tokens'],\n",
    "            \"input_token_index\": sequence_data['input_token_index'],\n",
    "            \"target_token_index\": sequence_data['target_token_index'],\n",
    "            \"num_thinking_steps\": settings_dict[\"thinking_steps\"],\n",
    "        }\n",
    "        \n",
    "        self.data_generator = DataGeneratorAttention(input_texts=input_texts,\n",
    "                                               target_texts=output_texts,\n",
    "                                               **data_gen_pars)\n",
    "        \n",
    "        if not teacher_forcing:\n",
    "            outputs_true, outputs_preds = self.predict_without_teacher(n_samples, max_seq_length)\n",
    "            exact_match = len([0 for out_true, out_preds in zip(outputs_true, outputs_preds) if out_true.strip()==out_preds.strip()])/len(outputs_true)\n",
    "        \n",
    "        else:\n",
    "            result = self.model.evaluate_generator(self.data_generator, verbose=1)\n",
    "            exact_match = result[1]\n",
    "            \n",
    "        return exact_match\n",
    "    \n",
    "    def return_prediction(self, input_texts, output_texts, teacher_forcing=False, batch_size=128, n_samples=1000):\n",
    "        max_seq_length  = max([len(txt_in)+len(txt_out) for txt_in, txt_out in zip(input_texts,output_texts)])\n",
    "        \n",
    "        data_gen_pars = {\n",
    "            \"batch_size\": 1,\n",
    "            \"max_encoder_seq_length\": sequence_data['max_encoder_seq_length'],\n",
    "            \"max_decoder_seq_length\": sequence_data['max_decoder_seq_length'],\n",
    "            \"num_encoder_tokens\": sequence_data['num_encoder_tokens'],\n",
    "            \"num_decoder_tokens\": sequence_data['num_decoder_tokens'],\n",
    "            \"input_token_index\": sequence_data['input_token_index'],\n",
    "            \"target_token_index\": sequence_data['target_token_index'],\n",
    "            \"num_thinking_steps\": settings_dict[\"thinking_steps\"],\n",
    "        }\n",
    "        \n",
    "        self.data_generator = DataGeneratorAttention(input_texts=input_texts,\n",
    "                                               target_texts=output_texts,\n",
    "                                               **data_gen_pars)\n",
    "        \n",
    "        preds = self.model.predict_generator(self.data_generator, verbose=0)\n",
    "            \n",
    "        return preds\n",
    "    \n",
    "    def predict_on_string(self, text, max_output_length=100):\n",
    "        \n",
    "        max_seq_length = len(text) + max_output_length\n",
    "\n",
    "        \n",
    "        data_gen_pars = {'batch_size': 1,\n",
    "            \"max_encoder_seq_length\": sequence_data['max_encoder_seq_length'],\n",
    "            \"max_decoder_seq_length\": sequence_data['max_decoder_seq_length'],\n",
    "            \"num_encoder_tokens\": sequence_data['num_encoder_tokens'],\n",
    "            \"num_decoder_tokens\": sequence_data['num_decoder_tokens'],\n",
    "            \"input_token_index\": sequence_data['input_token_index'],\n",
    "            \"target_token_index\": sequence_data['target_token_index'],\n",
    "            \"num_thinking_steps\": settings_dict[\"thinking_steps\"]\n",
    "                 }\n",
    "        \n",
    "        \n",
    "        self.data_generator = DataGeneratorAttention(input_texts=[text],\n",
    "                                               target_texts=['0'*max_output_length],\n",
    "                                               **data_gen_pars)\n",
    "        \n",
    "        outputs_true, outputs_preds = self.predict_without_teacher(1, max_seq_length)\n",
    "        \n",
    "        return outputs_preds[0].strip()\n",
    "\n",
    "    def predict_without_teacher(self, n_samples, max_seq_length, random=True):\n",
    "        \n",
    "        encoded_texts = [] \n",
    "        outputs_true = []\n",
    "        \n",
    "        if random:\n",
    "            samples = np.random.choice(self.data_generator.indexes, n_samples, replace=False)\n",
    "        else:\n",
    "            samples = list(range(n_samples))\n",
    "        for i in samples:\n",
    "            sample = self.data_generator._DataGeneratorAttention__data_generation([i])         \n",
    "            input_len = len(self.data_generator.input_texts[i])\n",
    "            outputs_true.append(self.data_generator.target_texts[i])\n",
    "            x = sample[0][0][:input_len+self.settings_dict[\"thinking_steps\"]+1]\n",
    "            encoded_texts.append(np.expand_dims(x, axis=0))\n",
    "            \n",
    "        outputs_preds = self.lstm.decode_sample(encoded_texts, self.token_index, max_seq_length)\n",
    "        return outputs_true, outputs_preds"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Load datasets"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "# job_ids = {1:'j4bu146wamlr9', 2: 'js0kldpwp1nhos', 3: 'jroi3ag4aros6'}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "job_ids = {1:'jsfd8uwubghbqg'}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 jsfd8uwubghbqg\n"
     ]
    }
   ],
   "source": [
    "for key, value in job_ids.items():\n",
    "    print(key, value)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "model_path = Path('../../../../artifacts/'  + job_ids[1])\n",
    "settings_dict, input_texts, target_texts = get_data(model_path/'settings.json')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'batch_size': 512,\n",
       " 'data_path': '/storage/git/deep-math/data/',\n",
       " 'embedding_dim': 256,\n",
       " 'epochs': 1,\n",
       " 'math_module': 'arithmetic',\n",
       " 'num_decoder_units': 2048,\n",
       " 'num_encoder_units': 512,\n",
       " 'save_path': '/artifacts/',\n",
       " 'thinking_steps': 16,\n",
       " 'train_level': '*'}"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "settings_dict"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "dict_keys(['target_token_index', 'target_texts', 'num_encoder_tokens', 'num_decoder_tokens', 'input_texts', 'max_encoder_seq_length', 'max_decoder_seq_length', 'input_token_index', 'num_thinking_steps'])"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "with open(str(model_path/'arithmetic-*.pkl'), 'rb') as file:\n",
    "    sequence_data = pickle.load(file)\n",
    "\n",
    "sequence_data.keys()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Evaluate datasets"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_sample=1024"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 203,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "W0921 10:12:18.242913 140434413999872 tf_logging.py:161] <tensorflow.python.keras.layers.recurrent.UnifiedLSTM object at 0x7fb355c920b8>: Note that this layer is not optimized for performance. Please use tf.keras.layers.CuDNNLSTM for better performance on GPU.\n",
      "W0921 10:12:18.246821 140434413999872 tf_logging.py:161] <tensorflow.python.keras.layers.recurrent.UnifiedLSTM object at 0x7fb361229748>: Note that this layer is not optimized for performance. Please use tf.keras.layers.CuDNNLSTM for better performance on GPU.\n",
      "W0921 10:12:19.143254 140434413999872 tf_logging.py:161] <tensorflow.python.keras.layers.recurrent.UnifiedLSTM object at 0x7fb37764cf60>: Note that this layer is not optimized for performance. Please use tf.keras.layers.CuDNNLSTM for better performance on GPU.\n"
     ]
    }
   ],
   "source": [
    "lstm_eval = LSTMWithAttentionEvaluator(model_path)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 183,
   "metadata": {},
   "outputs": [],
   "source": [
    "range_sample = slice(0,10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 184,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['((-9)/4 - ((-15)/(-84))/(17655/(-74151)))*((-18896)/(-84) + 0 - (-6)/(-21))',\n",
       " 'What is the value of 4*(-15)/(-10)*(-3 + (-15)/18*(-16)/10 - 8/(-48)) + 6 + -9?',\n",
       " '(578/(-680) - (0/(-3) + (-2)/(-5)))/(1 - 16 - 509504/(-34048))',\n",
       " 'Calculate ((28/(-21))/((-1)/4))/((-4)/3*(-22 - (21945/198)/(-5))).',\n",
       " 'What is 2792/(-29316)*(-3)/(-8) - (-18)/(-84) - (-2 - (-390)/16)/(-2*(-4)/(-48))?',\n",
       " 'Calculate 14*36/168*(4/((-72)/(-939)) - -3)/(9/6*((-2)/6 - 0)).',\n",
       " 'What is ((-41514)/(-55) + 10*(-259)/925)/(8/((-24)/9) + (1 + 0 - 0))?',\n",
       " 'Calculate (116/(-3))/(26319/(-175460) + (1 - (-347)/(-300))) - (4/46 + 0).',\n",
       " '((-3135)/190)/((-15)/7 - -3 - (1/10)/(7 - (5 - (-1694)/945)))',\n",
       " 'What is the value of (186 + -315 + 140 - ((-1204)/(-12))/((-1)/3)) + 1/(-1)*3*8/6?']"
      ]
     },
     "execution_count": 184,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "input_texts['extrapolate']['arithmetic__mixed_longer'][range_sample]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 194,
   "metadata": {},
   "outputs": [],
   "source": [
    "preds = lstm_eval.return_prediction(input_texts['extrapolate']['arithmetic__mixed_longer'][range_sample], target_texts['extrapolate']['arithmetic__mixed_longer'][range_sample])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 195,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 196,
   "metadata": {},
   "outputs": [],
   "source": [
    "itos = dict([(v, k) for k,v in sequence_data['target_token_index'].items()])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 197,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "slice(0, 10, None)"
      ]
     },
     "execution_count": 197,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "range_sample"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 198,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(10, 48, 30)"
      ]
     },
     "execution_count": 198,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "preds.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 199,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "-13/\n",
      "-6/\n",
      "-88/////////////////////////////\n",
      "-17/\n",
      "-18\n",
      "1188\n",
      "-///////////////////////////////\n",
      "-186\n",
      "126\n",
      "-17\n"
     ]
    }
   ],
   "source": [
    "indices = range(range_sample.start, range_sample.stop)\n",
    "\n",
    "for i, _ in enumerate(indices):\n",
    "    print(\"\".join([itos[j] for j in np.argmax(preds[i,16:], axis=1)]).split('\\n')[0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 190,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['\\t-337\\n',\n",
       " '\\t-12\\n',\n",
       " '\\t35\\n',\n",
       " '\\t-24\\n',\n",
       " '\\t134\\n',\n",
       " '\\t-331\\n',\n",
       " '\\t-376\\n',\n",
       " '\\t126\\n',\n",
       " '\\t-44\\n',\n",
       " '\\t308\\n']"
      ]
     },
     "execution_count": 190,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "target_texts['extrapolate']['arithmetic__mixed_longer'][range_sample]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 166,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['Calculate (-1)/3 + (91770/(-1380)*(-2)/57 - (-13)/(-1)) - (-57 + -200).',\n",
       " 'Evaluate 21/(-1953)*-31*(4 + 143) - ((-402)/67*4/(-3))/(1 + 3*-1).',\n",
       " 'Calculate ((-3)/(-7)*(-6)/(-9))/((-1)/7*-1*(1146/2928 - (2075/200 + -10))).',\n",
       " '(506/35)/((-3746)/(-28095)) + (-2 + 62/28)/((-18)/720*-15)',\n",
       " 'Calculate (108/(-60))/((-2)/(-5))*(-8 + (1 + 5 + 6 + (-66)/4)*12/27).',\n",
       " '(6 - (3 - (-12)/6)) + (0 - -10)/(15*(-5)/(-30))*51*(-4)/16',\n",
       " '((6/2)/1)/(1/6 + 17 + (-1696794)/99180 + (-6)/(-435)*-295 + 4)',\n",
       " '(((-40)/14)/5*(-1)/(20/14) - ((-28800)/(-540))/(125/440))/(2/3)',\n",
       " 'Evaluate ((-812)/28 - -24) + 9/270*6*(-495)/(-6)*(-36)/(-27).',\n",
       " 'What is (4/(-468)*-9 - ((-103499)/15132 - (-14)/2) - 1/6) + 2918/(-8)*1?']"
      ]
     },
     "execution_count": 166,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "input_texts['extrapolate']['arithmetic__mixed_longer'][range_sample]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 200,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "10/10 [==============================] - 3s 301ms/step - loss: 2.0773 - exact_match_metric: 0.0000e+00\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "0.0"
      ]
     },
     "execution_count": 200,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "lstm_eval.evaluate_model(input_texts['extrapolate']['arithmetic__mixed_longer'][range_sample], target_texts['extrapolate']['arithmetic__mixed_longer'][range_sample])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "W0921 10:14:45.764673 140531860117248 tf_logging.py:161] <tensorflow.python.keras.layers.recurrent.UnifiedLSTM object at 0x7fcbec1d9dd8>: Note that this layer is not optimized for performance. Please use tf.keras.layers.CuDNNLSTM for better performance on GPU.\n",
      "W0921 10:14:45.768177 140531860117248 tf_logging.py:161] <tensorflow.python.keras.layers.recurrent.UnifiedLSTM object at 0x7fcbec1f3240>: Note that this layer is not optimized for performance. Please use tf.keras.layers.CuDNNLSTM for better performance on GPU.\n",
      "W0921 10:14:50.042084 140531860117248 tf_logging.py:161] <tensorflow.python.keras.layers.recurrent.UnifiedLSTM object at 0x7fcbe94e8908>: Note that this layer is not optimized for performance. Please use tf.keras.layers.CuDNNLSTM for better performance on GPU.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "EPOCH 1\n",
      "19/19 [==============================] - 32s 2s/step - loss: 0.5992 - exact_match_metric: 0.4062\n",
      "19/19 [==============================] - 31s 2s/step - loss: 3.7665 - exact_match_metric: 0.0107\n",
      "19/19 [==============================] - 31s 2s/step - loss: 2.0038 - exact_match_metric: 0.3914\n",
      "19/19 [==============================] - 31s 2s/step - loss: 0.7114 - exact_match_metric: 0.2369\n",
      "19/19 [==============================] - 31s 2s/step - loss: 0.8487 - exact_match_metric: 0.5917\n",
      "19/19 [==============================] - 31s 2s/step - loss: 0.4580 - exact_match_metric: 0.5604\n",
      "19/19 [==============================] - 31s 2s/step - loss: 1.1629 - exact_match_metric: 0.1299\n",
      "19/19 [==============================] - 31s 2s/step - loss: 0.3720 - exact_match_metric: 0.6763\n",
      "19/19 [==============================] - 31s 2s/step - loss: 0.4548 - exact_match_metric: 0.6896\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "for epoch, job_id in job_ids.items():\n",
    "    model_path = Path('../../../../artifacts/'  + job_id)\n",
    "    lstm_eval = LSTMWithAttentionEvaluator(model_path)\n",
    "    print('EPOCH', epoch)\n",
    "    res, res_dm = evaluate_arithmetics_interpolate(lstm_eval, input_texts, target_texts)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "W0921 10:21:39.448930 140531860117248 tf_logging.py:161] <tensorflow.python.keras.layers.recurrent.UnifiedLSTM object at 0x7fcb017a7518>: Note that this layer is not optimized for performance. Please use tf.keras.layers.CuDNNLSTM for better performance on GPU.\n",
      "W0921 10:21:39.452140 140531860117248 tf_logging.py:161] <tensorflow.python.keras.layers.recurrent.UnifiedLSTM object at 0x7fcb017b3518>: Note that this layer is not optimized for performance. Please use tf.keras.layers.CuDNNLSTM for better performance on GPU.\n",
      "W0921 10:21:40.867962 140531860117248 tf_logging.py:161] <tensorflow.python.keras.layers.recurrent.UnifiedLSTM object at 0x7fcaff26df28>: Note that this layer is not optimized for performance. Please use tf.keras.layers.CuDNNLSTM for better performance on GPU.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "EPOCH 1\n",
      "19/19 [==============================] - 36s 2s/step - loss: 2.1095 - exact_match_metric: 0.0043\n",
      "19/19 [==============================] - 31s 2s/step - loss: 1.7000 - exact_match_metric: 0.0455\n",
      "19/19 [==============================] - 31s 2s/step - loss: 1.8211 - exact_match_metric: 0.0557\n",
      "19/19 [==============================] - 31s 2s/step - loss: 4.3193 - exact_match_metric: 0.2311\n",
      "19/19 [==============================] - 31s 2s/step - loss: 1.2828 - exact_match_metric: 0.4660\n",
      "19/19 [==============================] - 31s 2s/step - loss: 1.8079 - exact_match_metric: 0.4275\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "for epoch, job_id in job_ids.items():\n",
    "    model_path = Path('../../../../artifacts/'  + job_id)\n",
    "    lstm_eval = LSTMWithAttentionEvaluator(model_path)\n",
    "    print('EPOCH', epoch)\n",
    "    res, res_dm = evaluate_arithmetics_extrapolate(lstm_eval, input_texts, target_texts)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
